package com.qf.controller;

import com.qf.service.DtsCategoryService;
import com.qf.service.DtsOrderService;
import com.qf.service.DtsUserService;
import com.qf.util.ResponseUtil;
import com.qf.vo.*;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author lixu
 */
@RequestMapping("/admin/dashboard")
@RestController
@CrossOrigin
public class DashboardController {


    @Autowired
    private DtsCategoryService dtsCategoryService;
    @Autowired
    private DtsOrderService dtsOrderService;
    @Autowired
    private DtsUserService dtsUserService;

    public static final Integer STATIS_DAY_NUM = 30;

    /**
     * - 首页统计用户数, 商品数, 库存货品数,订单数地址 : http://localhost:8083/admin/dashboard
     * - GET请求
     * - 下行数据 :
     * - goodsTotal : 商品数量, userTotal : 用户数量 , productTotal : 货品数量 , orderTotal : 订单数量
     * {
     * "errno":0,
     * "data":{
     * "goodsTotal":426,
     * "userTotal":197,
     * "productTotal":8939,
     * "orderTotal":107
     * },
     * "errmsg":"成功"
     * }
     */
    @RequiresUser
    @GetMapping
    public Object dashboard() {

        //同学们写查询数据库
        Map data = new HashMap<>();
        data.put("goodsTotal", 426);
        data.put("userTotal", 197);
        data.put("productTotal", 8939);
        data.put("orderTotal", 107);
        return ResponseUtil.ok(data);
    }

    /**
     * /chart
     * <p>
     * - 首页数据可视化图表地址 : http://localhost:8083/admin/dashboard/chart
     * <p>
     * - GET请求
     * <p>
     * - 下行数据 :
     * <p>
     * - categorySell : 商品分类  和对应分类的销售额
     */
    @RequiresUser
    @GetMapping("/chart")
    public Object chart() {
        //1:查询商品分类和对应分类的销售额
        List<CategorySellAmts> categorySellAmtsList = dtsCategoryService.
                findGoodsCategoryAndTotal();
        CategorySellVo categorySellVo = new CategorySellVo();
        categorySellVo.setCategorySellData(categorySellAmtsList);
        //商品分类的数组
        String[] categoryNames = categorySellAmtsList.stream()
                .map(CategorySellAmts::getName).collect(Collectors.toList())
                .toArray(new String[categorySellAmtsList.size()]);
        categorySellVo.setCategoryNames(categoryNames);


        //2:日期和对应的订单总额, 订单笔数
        List<DayStatis> dayStatisList = dtsOrderService.findDayStatis();
        //3:日期对应的用户数和订单数
        OrderAmtsVo orderAmtsVo = new OrderAmtsVo();
        orderAmtsVo.setDayData(dayStatisList.stream().map(DayStatis::getDayStr).
                collect(Collectors.toList()).toArray(new String[dayStatisList.size()]));
        orderAmtsVo.setOrderCntData(dayStatisList.stream().map(DayStatis::getCnts).
                collect(Collectors.toList()).toArray(new Integer[dayStatisList.size()]));
        orderAmtsVo.setOrderAmtData(dayStatisList.stream().map(DayStatis::getAmts)
                .collect(Collectors.toList()));

        //3:userOrderCnt : 日期对应的用户数和订单数
        //3.1：查询日期对应的订单数 上面有
        //3.2：查询日期对应的用户数
        List<DayStatis> dayStatisListByUser = dtsUserService.findDayStatis(STATIS_DAY_NUM);


        UserOrderCntVo userOrderCntVo = new UserOrderCntVo();
        //日期数据  文档：只考虑了 有订单没有用户必须有日期  没有订单但有用户必须有日期 | 没有订单/没有用户的日期
        String[] dayData = fetchDayData(dayStatisList, dayStatisListByUser);
        //
        userOrderCntVo.setDayData(dayData);
        ////每日用户新增量
        Integer[] userCnt = fetchUserOrOrderCnt(dayData, dayStatisListByUser);
        userOrderCntVo.setUserCnt(userCnt);
        //每日订单量
        Integer[] orderCnt = fetchUserOrOrderCnt(dayData, dayStatisList);
        userOrderCntVo.setOrderCnt(orderCnt);
        Map data = new HashMap<>();
        data.put("categorySell", categorySellVo);
        data.put("orderAmts", orderAmtsVo);
        data.put("userOrderCnt", userOrderCntVo);
        return ResponseUtil.ok(data);
    }

    /**
     * 合并日期后 对应的用户数   合并日期后对应的订单数
     *
     * @param dayData
     * @return
     */
    private Integer[] fetchUserOrOrderCnt(String[] dayData, List<DayStatis> dayStatisList) {
        List<Integer> cnts = new ArrayList<>();
       //   Key:日期 Value：用户数|订单数
        Map<String,Integer> dayStatisMap = dayStatisList.stream()
                .collect(Collectors.toMap(DayStatis::getDayStr,DayStatis::getCnts));
        Arrays.stream(dayData).forEach(day -> {
            Integer cnt = dayStatisMap.get(day);
            if(cnt == null){
                //当日没有新增
                cnts.add(0);
            }else{
                cnts.add(cnt);
            }
        });
        return cnts.toArray(new Integer[cnts.size()]);
    }

    /**
     * 合并用户及订单对应的日期
     *
     * @param dayStatisList
     * @param dayStatisListByUser
     * @return
     */
    private String[] fetchDayData(List<DayStatis> dayStatisList, List<DayStatis> dayStatisListByUser) {

        //日期
        Set<String> set = new HashSet<>();

        dayStatisList.forEach(dayStatis -> {
      /*      if(dayStatis.getDayStr() != null){
                set.add(dayStatis.getDayStr());
            }*/
            Optional.ofNullable(dayStatis.getDayStr()).ifPresent(set::add);
        });

        dayStatisListByUser.forEach(dayStatis -> {
            Optional.ofNullable(dayStatis.getDayStr()).ifPresent(set::add);
        });
        //Lambda 排序 Stream流 比较器
        /**
         * 比较器 :
         *    T o1 前一值
         *    T o1 后一值
         *    返回值 ： > 0 由高到低  < 0 由低到高  =0 不排序
         *     int compare(T o1, T o2);
         */
        //return set.stream().sorted((s1,s2) -> s2.compareTo(s1)).collect(Collectors.toList()).toArray(new String[set.size()]);
        return set.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList()).toArray(new String[set.size()]);
    }


}
